package baiqitun.stupro.common.service.support;

import baiqitun.stupro.common.constant.SysConstant;
import baiqitun.stupro.common.entity.Entity;
import baiqitun.stupro.common.service.DataService;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Optional;

/**
 * @author kedaji
 * @param <E>
 */

@Slf4j
public class MongoDataService<E extends Entity> implements DataService<E> {
    @Autowired
    protected MongoRepository<E, String> repository;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean save(E e) {
        e.setId(IdUtil.fastUUID()).setCreateDateTime(LocalDateTime.now())
                .setSortId(IdUtil.createSnowflake(SysConstant.SNOWFLAKE_WORKER_ID, SysConstant.SNOWFLAKE_DATA_CENTER_ID).nextId())
                .setDeleted("0");
        E savedEntity = repository.save(e);
        while (savedEntity == null){
            savedEntity = repository.save(e);
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeById(String id) {
        repository.deleteById(id);
        return true;
    }

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    @Override
    public E getById(String id) {
        Optional<E> optional = repository.findById(id);
        return optional.isPresent() ? optional.get() : null;
    }


    @Transactional(readOnly = true, rollbackFor = Exception.class)
    @Override
    public IPage<E> page(int pageNo, int pageSize, E element){
        PageRequest pageRequest = PageRequest.of(pageNo, pageSize, Sort.Direction.DESC, "createBy","sortId");
        Page<E> tmpPage = null;
        if (element != null){
            Example<E> example = Example.of(element);
            tmpPage = repository.findAll(example, pageRequest);
        } else {
            tmpPage = repository.findAll(pageRequest);
        }

        IPage<E> page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>();
        page.setCurrent(pageNo).setSize(pageSize).setRecords(tmpPage.getContent()).setPages(tmpPage.getTotalPages()).setTotal(tmpPage.getTotalElements());
        return page;
    }
}
